// Copyright 2012 Google, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


#include <stdlib.h>

#include <iostream>

#include "inetsocket.h"
#include "pollserver.h"
#include "rand.h"


using namespace PerRequestIPv6Address;


int main(int argc, const char** argv) {
  // [0] Parse flags and respond appropriately.

  RandomSource random_src;

  // [1] Setup multiplexing infrastructure.
  PollServer poller;

  // [2] Start upstream query/listening socket.
  // Forwarder forwarder(poller, random_src);
  uint16_t upstreamPort = random_src.getUnsigned16();
  for (int repeat = 0;
       upstreamPort == 0 && repeat < 5;
       upstreamPort = random_src.getUnsigned16(), repeat++) {}
  std::cout << "using upstreamPort: " << upstreamPort << std::endl;

  InetSocket upstreamUdp;
  for (int repeat = 0;
       !NewUpstreamUDPSocket(&upstreamUdp, upstreamPort) && repeat < 5;
       repeat++) {}

  // [3] Start local query/listening sockets.
  uint16_t localPort = random_src.getUnsigned16();
  for (int repeat = 0;
       localPort == 0 && repeat < 5;
       localPort = random_src.getUnsigned16(), repeat++) {}
  std::cout << "using localPort: " << localPort << std::endl;

  // Listener listener(poller, forwarder, localPort);
  InetSocket localUdp;
  if (!NewLocalUDPSocket(&localUdp, localPort) ||
      localUdp.localPort() != localPort) {
    std::cerr << "Failed to create local UDP socket" << std::endl;
    ::exit(-1);
  }

  InetSocket localTcp;
  if (!NewLocalTCPSocket(&localTcp, localPort) ||
      localTcp.localPort() != localPort) {
    std::cerr << "Failed to create local TCP socket" << std::endl;
    ::exit(-1);
  }

  // [4] Loop forever.
  // Run test code...for now.
  TestSendFromRandomSourceAddress(&upstreamUdp);

  // [5] Close up shop.
}
